package org.ucas.faker.web.utils.model;

import com.alibaba.fastjson.JSONObject;
import org.ucas.faker.web.entity.patents.Agency;
import org.ucas.faker.web.entity.patents.Symbol;

import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.util.*;

public class RawPatent implements Documentable {

  @Transient
  private Map<Iterable, Iterator> iters = new HashMap<>();

  public Long id;

  public String sourceId; // 万象云ID

  public String source; // 专利来源

  public String ti; // 专利标题

  public String ab; // 专利摘要

  public String ts; // 标题 & 摘要

  public String cl; // 权利要求

  public String ds; // 说明书

  public String an; // 申请号

  public String ad; // 申请日期

  public String ro; //receiving office受理局
  
  public String pn; // 公开号

  public String pd; // 公开(公告)日

  public List<Symbol> prn= new ArrayList();; // 优先权
//  public String prn; // 优先权号

  public String prd; // 优先权日期

  public String pt; // 专利类别

  public List<Agency> applicants = new ArrayList<>(); // 申请人

//  public String ap; // 申请人
//
//  public String apc; // 申请人所在国

//  public String apad; // 申请人地址
  
  public String apr; //省份

  public Integer ap_count; // 申请人数量

  public Integer ap_year; // 申请年


  public List<Agency> pa = new ArrayList<>(); // 专利权人

//  public String pa; // 专利权人
//
//  public String pac; // 专利权人所在国
//
//  public String pacp; // 专利权人所在国代码
//
//  public String paad; // 专利权人地址

  public Integer pa_count; // 专利权人数量

  public List<Agency> in = new ArrayList<>(); // 发明人

//  public String in; // 发明人

  public Integer in_count; // 发明人数量

  public List<Symbol> ipcs = new ArrayList();
//  public String ic; // IPC 分类号

  public List<Symbol> icm= new ArrayList(); // IPC 主分类号

  public Integer ipc_count; // IPC分类号数量

  public List<Symbol> cpcs= new ArrayList();

//  public String cpc; // 联合国专利分类号

  public Integer cpc_count; // CPC分类号数量

  public String ccm; // CPC主分类号

  public String lc; // 国际外观设计分类号

  public String fm; // 基本专利族专利号

  public String ifm; // 扩展专利族专利号

  public Integer fm_count; // 基本专利族专利数量

  public Integer ifm_count; // 扩展专利族专利数量


  // 引用字段

  public String cb; // 引用专利情况

  public Integer cbt; // 引用类型

  public String cbr; // 引用说明

  public String cbap; // 引用专利申请人

  public Integer cb_scount; // 引用专利数量

  public Integer cb_fcount; // 基本专利族引用专利数量

  public Integer cb_count; // 扩展专利族引用专利数量

  public String cf; // 被专利引用情况

  public String cfr; // 被引用说明

  public String cfap; // 被引用专利申请人

  public Integer cf_scount; // 被引用专利数量

  public Integer cf_fcount; // 基本专利族被引用专利数量

  public Integer cf_count; // 扩展专利族被引用专利数量

  public String cfl; // 被引用文献

  // 法律状态字段

  public Integer ls; // 法律状态,s值为0（未知）、1（未授权）、2（有效）、3（已失效）

  public Integer ath; // 专利是否曾授权

  public String gd; // 	授权日

  public String ld; // 失效日

  public Integer prl; // 	专利预期剩余寿命

  public String lhsc; // 法律状态详情类型

  public String lhsd; // 法律状态详情公告日

  public String lhsp; // 法律状态详情描述


  // 权利许可字段

  public String lcp1; // 专利权许可许可人

  public String lcp2; // 专利权许可被许可人

  public String lcpd; // 专利权许可事件日期


  // 特殊字段

  public List<Symbol> br = new ArrayList<Symbol>(); //技术分支

  public List<Symbol> ef = new ArrayList<Symbol>(); //技术功效

  public Double value;

  public <T> T next(Iterable<T> collection) {
    if (collection == null) return null;
    Iterator<T> iter = iters.getOrDefault(collection, null);
    if (iter == null) {
      iter = collection.iterator();
      iters.put(collection, iter);
    }
    return iter.hasNext() ? iter.next() : null;
  }

  public List<Agency> agencies() {
    List<Agency> res = new ArrayList<>();
    if(applicants!=null)
    	res.addAll(applicants);
    if(pa!=null)
    	res.addAll(pa);
    if(in!=null)
    	res.addAll(in);
    return res;
  }

  public List<Symbol> symbols() {
    List<Symbol> res = new ArrayList<>();
    if(ipcs!=null)
    	res.addAll(ipcs);
    if(icm != null)
    	res.addAll(icm);
    if(cpcs!=null)
    	res.addAll(cpcs);
    if(prn!=null)
    	res.addAll(prn);
    if(ef != null)
      res.addAll(ef);
    if(br != null)
      res.addAll(br);
    return res;
  }



  @Override
  public String documentId() {
    return null;
  }


  @Override
  public void fromJson(JSONObject json) {
    for (Field field : this.getClass().getDeclaredFields()) {
      field.setAccessible(true);
      try {
        if (json.containsKey(field.getName())) {
          Object value = field.get(this);
          field.set(this, json.get(field.getName()));
        }

      } catch (IllegalAccessException e) {

      }
    }
  }

  @Override
  public JSONObject toJson() {
    JSONObject json = new JSONObject();
    for (Field field : this.getClass().getDeclaredFields()) {
      field.setAccessible(true);
      try {
        Object value = field.get(this);
        if (value != null)
          json.put(field.getName(), value);
      } catch (IllegalAccessException e) {
        json.remove(field.getName());
      }
    }
    return json;
  }


  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getSourceId() {
    return sourceId;
  }

  public void setSourceId(String sourceId) {
    this.sourceId = sourceId;
  }

  public String getSource() {
    return source;
  }

  public void setSource(String source) {
    this.source = source;
  }

  public String getTi() {
    return ti;
  }

  public void setTi(String ti) {
    this.ti = ti;
  }

  public String getAb() {
    return ab;
  }

  public void setAb(String ab) {
    this.ab = ab;
  }

  public String getTs() {
    if (ts == null) ts = ti + ab;
    return ts;
  }

  public void setTs(String ts) {
    this.ts = ts;
  }

  public String getCl() {
    return cl;
  }

  public void setCl(String cl) {
    this.cl = cl;
  }

  public String getDs() {
    return ds;
  }

  public void setDs(String ds) {
    this.ds = ds;
  }

  public String getAn() {
    return an;
  }

  public void setAn(String an) {
    this.an = an;
  }

  public String getAd() {
    return ad;
  }

  public void setAd(String ad) {
    this.ad = ad;
  }
  public String getRo() {
		return ro;
	}

	public void setRo(String ro) {
		this.ro = ro;
	}
	
  public String getPn() {
    return pn;
  }

  public void setPn(String pn) {
    this.pn = pn;
  }

  public String getPd() {
    return pd;
  }

  public void setPd(String pd) {
    this.pd = pd;
  }

  public String getPrd() {
    return prd;
  }

  public void setPrd(String prd) {
    this.prd = prd;
  }

  public String getPt() {
    return pt;
  }

  public void setPt(String pt) {
    this.pt = pt;
  }



  public Integer getAp_count() {
    return ap_count;
  }

  public void setAp_count(Integer ap_count) {
    this.ap_count = ap_count;
  }



  public Integer getPa_count() {
    return pa_count;
  }

  public void setPa_count(Integer pa_count) {
    this.pa_count = pa_count;
  }



  public Integer getIn_count() {
    return in_count;
  }

  public void setIn_count(Integer in_count) {
    this.in_count = in_count;
  }


  public List<Symbol> getIcm() {
    return icm;
  }

  public void setIcm(List<Symbol> icm) {
    this.icm = icm;
  }

  public Integer getIpc_count() {
    return ipc_count;
  }

  public void setIpc_count(Integer ipc_count) {
    this.ipc_count = ipc_count;
  }



  public Integer getCpc_count() {
    return cpc_count;
  }

  public void setCpc_count(Integer cpc_count) {
    this.cpc_count = cpc_count;
  }

  public String getLc() {
    return lc;
  }

  public void setLc(String lc) {
    this.lc = lc;
  }

  public String getFm() {
    return fm;
  }

  public void setFm(String fm) {
    this.fm = fm;
  }

  public String getIfm() {
    return ifm;
  }

  public void setIfm(String ifm) {
    this.ifm = ifm;
  }

  public Integer getFm_count() {
    return fm_count;
  }

  public void setFm_count(Integer fm_count) {
    this.fm_count = fm_count;
  }

  public Integer getIfm_count() {
    return ifm_count;
  }

  public void setIfm_count(Integer ifm_count) {
    this.ifm_count = ifm_count;
  }

  public String getCb() {
    return cb;
  }

  public void setCb(String cb) {
    this.cb = cb;
  }

  public Integer getCbt() {
    return cbt;
  }

  public void setCbt(Integer cbt) {
    this.cbt = cbt;
  }

  public String getCbr() {
    return cbr;
  }

  public void setCbr(String cbr) {
    this.cbr = cbr;
  }

  public String getCbap() {
    return cbap;
  }

  public void setCbap(String cbap) {
    this.cbap = cbap;
  }

  public Integer getCb_scount() {
    return cb_scount;
  }

  public void setCb_scount(Integer cb_scount) {
    this.cb_scount = cb_scount;
  }

  public Integer getCb_fcount() {
    return cb_fcount;
  }

  public void setCb_fcount(Integer cb_fcount) {
    this.cb_fcount = cb_fcount;
  }

  public Integer getCb_count() {
    return cb_count;
  }

  public void setCb_count(Integer cb_count) {
    this.cb_count = cb_count;
  }

  public String getCf() {
    return cf;
  }

  public void setCf(String cf) {
    this.cf = cf;
  }

  public String getCfr() {
    return cfr;
  }

  public void setCfr(String cfr) {
    this.cfr = cfr;
  }

  public String getCfap() {
    return cfap;
  }

  public void setCfap(String cfap) {
    this.cfap = cfap;
  }

  public Integer getCf_scount() {
    return cf_scount;
  }

  public void setCf_scount(Integer cf_scount) {
    this.cf_scount = cf_scount;
  }

  public Integer getCf_fcount() {
    return cf_fcount;
  }

  public void setCf_fcount(Integer cf_fcount) {
    this.cf_fcount = cf_fcount;
  }

  public Integer getCf_count() {
    return cf_count;
  }

  public void setCf_count(Integer cf_count) {
    this.cf_count = cf_count;
  }

  public String getCfl() {
    return cfl;
  }

  public void setCfl(String cfl) {
    this.cfl = cfl;
  }

  public Integer getLs() {
    return ls;
  }

  public void setLs(Integer ls) {
    this.ls = ls;
  }

  public Integer getAth() {
    return ath;
  }

  public void setAth(Integer ath) {
    this.ath = ath;
  }

  public String getGd() {
    return gd;
  }

  public void setGd(String gd) {
    this.gd = gd;
  }

  public String getLd() {
    return ld;
  }

  public void setLd(String ld) {
    this.ld = ld;
  }

  public Integer getPrl() {
    return prl;
  }

  public void setPrl(Integer prl) {
    this.prl = prl;
  }

  public String getLhsc() {
    return lhsc;
  }

  public void setLhsc(String lhsc) {
    this.lhsc = lhsc;
  }

  public String getLhsd() {
    return lhsd;
  }

  public void setLhsd(String lhsd) {
    this.lhsd = lhsd;
  }

  public String getLhsp() {
    return lhsp;
  }

  public void setLhsp(String lhsp) {
    this.lhsp = lhsp;
  }

  public String getLcp1() {
    return lcp1;
  }

  public void setLcp1(String lcp1) {
    this.lcp1 = lcp1;
  }

  public String getLcp2() {
    return lcp2;
  }

  public void setLcp2(String lcp2) {
    this.lcp2 = lcp2;
  }

  public String getLcpd() {
    return lcpd;
  }



  public Double getValue() {
    return value;
  }

  public void setValue(Double value) {
    this.value = value;
  }

  public String getCcm() {

    return ccm;
  }

  public void setCcm(String ccm) {
    this.ccm = ccm;
  }

  public void setLcpd(String lcpd) {
    this.lcpd = lcpd;
  }

  public Integer getAp_year() {
    return ap_year;
  }

  public void setAp_year(Integer ap_year) {
    this.ap_year = ap_year;
  }

public Map<Iterable, Iterator> getIters() {
	return iters;
}

public void setIters(Map<Iterable, Iterator> iters) {
	this.iters = iters;
}

public List<Symbol> getPrn() {
	return prn;
}

public void setPrn(List<Symbol> prn) {
	this.prn = prn;
}

public List<Agency> getApplicants() {
	return applicants;
}

public void setApplicants(List<Agency> applicants) {
	this.applicants = applicants;
}

public String getApr() {
	return apr;
}

public void setApr(String apr) {
	this.apr = apr;
}

public List<Agency> getPa() {
	return pa;
}

public void setPa(List<Agency> pa) {
	this.pa = pa;
}

public List<Agency> getIn() {
	return in;
}

public void setIn(List<Agency> in) {
	this.in = in;
}

public List<Symbol> getIpcs() {
	return ipcs;
}

public void setIpcs(List<Symbol> ipcs) {
	this.ipcs = ipcs;
}

public List<Symbol> getCpcs() {
	return cpcs;
}

public void setCpcs(List<Symbol> cpcs) {
	this.cpcs = cpcs;
}

public List<Symbol> getBr() {
	return br;
}

public void setBr(List<Symbol> br) {
	this.br = br;
}

public List<Symbol> getEf() {
	return ef;
}

public void setEf(List<Symbol> ef) {
	this.ef = ef;
}



}
